package com.jsyso.jsyso.db;

import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;

/**
 * 数据库where条件
 * @author janjan, xujian_jason@163.com
 *
 */
public class Wheres {
	// 一般查询条件都 <= 6 
	private static final int DEFAULT_WHERE_NUM = 6;
	private Map<String, Object> map;
	
	public Wheres() {
		this.map = new LinkedHashMap<String, Object>(DEFAULT_WHERE_NUM);
	}
	
	public Wheres(Map<String, Object> map) {
		this.map = map;
	}
	
	public static Wheres create() {
		return new Wheres();
	}
	
	public static Wheres create(Collection<String> keys) {
		return new Wheres().setKeys(keys);
	}
	
	public static Wheres create(String key) {
		return new Wheres().set(key);
	}
	
	public static Wheres create(String key, Object value) {
		return new Wheres().set(key, value);
	}
	
	public Wheres set(String key, Object value) {
		this.map.put(key, value);
		return this;
	}
	
	public Wheres set(String key) {
		this.set(key, null);
		return this;
	}
	
	public Wheres setKeys(Collection<String> keys) {
		if(keys != null && !keys.isEmpty()) {
			for(String key : keys) {
				this.set(key);
			}
		}
		return this;
	}
	
	public Wheres eq(String key, Object value) {
		if(value == null) {
			return this;
		}
		this.map.put(key, new Object[]{Dialect.EXP_EQ, value});
		return this;
	}
	
	public Wheres eq(String key) {
		this.eq(key, null);
		return this;
	}
	
	public Wheres neq(String key, Object value) {
		if(value == null) {
			return this;
		}
		this.set(key, new Object[]{Dialect.EXP_NEQ, value});
		return this;
	}
	
	public Wheres neq(String key) {
		this.neq(key, null);
		return this;
	}
	
	public Wheres gt(String key, Object value) {
		if(value == null) {
			return this;
		}
		this.set(key, new Object[]{Dialect.EXP_GT, value});
		return this;
	}
	
	public Wheres gt(String key) {
		this.gt(key, null);
		return this;
	}
	
	public Wheres egt(String key, Object value) {
		if(value == null) {
			return this;
		}
		this.set(key, new Object[]{Dialect.EXP_EGT, value});
		return this;
	}
	
	public Wheres egt(String key) {
		this.egt(key, null);
		return this;
	}
	
	public Wheres lt(String key, Object value) {
		if(value == null) {
			return this;
		}
		this.set(key, new Object[]{Dialect.EXP_LT, value});
		return this;
	}
	
	public Wheres lt(String key) {
		this.lt(key, null);
		return this;
	}
	
	public Wheres elt(String key, Object value) {
		if(value == null) {
			return this;
		}
		this.set(key, new Object[]{Dialect.EXP_ELT, value});
		return this;
	}
	
	public Wheres elt(String key) {
		this.elt(key, null);
		return this;
	}
	
	public Wheres notlike(String key, Object value) {
		if(value == null) {
			return this;
		}
		this.set(key, new Object[]{Dialect.EXP_NOTLIKE, value});
		return this;
	}
	
	public Wheres notlike(String key) {
		this.notlike(key, null);
		return this;
	}
	
	public Wheres like(String key, Object value) {
		if(value == null) {
			return this;
		}
		this.set(key, new Object[]{Dialect.EXP_LIKE, value});
		return this;
	}
	
	public Wheres like(String key) {
		this.like(key, null);
		return this;
	}
	
	public Wheres in(String key, Object value) {
		if(value == null) {
			return this;
		}
		this.set(key, new Object[]{Dialect.EXP_IN, value});
		return this;
	}
	
	public Wheres in(String key) {
		this.in(key, null);
		return this;
	}
	
	public Wheres notin(String key, Object value) {
		if(value == null) {
			return this;
		}
		this.set(key, new Object[]{Dialect.EXP_NOTIN, value});
		return this;
	}
	
	public Wheres notin(String key) {
		this.notin(key, null);
		return this;
	}
	
	public Wheres between(String key, Object value) {
		if(value == null) {
			return this;
		}
		this.set(key, new Object[]{Dialect.EXP_BETWEEN, value});
		return this;
	}
	
	public Wheres between(String key) {
		this.between(key, null);
		return this;
	}
	
	public Wheres notbetween(String key, Object value) {
		if(value == null) {
			return this;
		}
		this.set(key, new Object[]{Dialect.EXP_NOTBETWEEN, value});
		return this;
	}
	
	public Wheres notbetween(String key) {
		this.notbetween(key, null);
		return this;
	}
	
	public Wheres exp(String key, String value) {
		if(StringUtils.isBlank(value)) {
			return this;
		}
		this.set(key, new Object[]{"exp", value});
		return this;
	}
	
	public Wheres remove(String key) {
		this.map.remove(key);
		return this;
	}
	
	@SuppressWarnings("unchecked")
	public <T> T get(String key) {
		return (T) this.map.get(key);
	}
	
	public Wheres clear() {
        this.map.clear();
        return this;
    }
	
	public Set<String> keySet() {
		return this.map.keySet();
	}
	
	public int size() {
		return this.map.size();
	}
	
	public boolean isEmpty() {
		return this.map.isEmpty();
	}
	
	public boolean containsKeys(Object[] keys) {
		if(keys == null || keys.length == 0) {
			return false;
		}
		for(Object key : keys) {
			if(!this.map.containsKey(key)) {
				return false;
			}
		}
		return true;
	}
	
}
